package article3

import (
	"bbs-web/internal/domain"
	event "bbs-web/internal/events/article"
	"bbs-web/internal/repository/article"
	"bbs-web/pkg/logger"
	"context"
	"time"
)

//go:generate mockgen -source=./articleService.go -package=svcmocks -destination=../svcmocks/articleService.mock.go
type articleService struct {
	repo     article5.ArticleRepository
	l        logger.Logger
	producer event.Producer
	ch       chan readInfo
}

type readInfo struct {
	Uid int64
	Aid int64
}

func NewArticleService(repo article5.ArticleRepository, l logger.Logger, producer event.Producer) IArticleService {
	return &articleService{repo: repo, l: l, producer: producer}
}

func (svc *articleService) ListPub(ctx context.Context, start time.Time, offset, limit int) ([]domain.Article, error) {

	return svc.repo.ListPub(ctx, start, offset, limit)
}

func (svc *articleService) List(ctx context.Context, uid int64, offset int, limit int) ([]domain.Article, error) {
	return svc.repo.List(ctx, uid, offset, limit)
}

func (svc *articleService) Save(ctx context.Context, art domain.Article) (int64, error) {
	//service层控制文章状态，如果id=0就是新建，其他就是更改
	art.Status = domain.ArticleStatusUnpublished
	if art.Id > 0 {
		err := svc.repo.Update(ctx, art)
		return art.Id, err
	}
	id, err := svc.repo.Create(ctx, art)
	return id, err
}

func (svc *articleService) Publish(ctx context.Context, art domain.Article) (int64, error) {
	//service层控制文章状态，如果id=0就是新建，其他就是更改
	art.Status = domain.ArticleStatusPublished
	id, err := svc.repo.Sync(ctx, art)
	return id, err
}

func (svc *articleService) Withdraw(ctx context.Context, art domain.Article) error {
	//service层控制文章状态，下架就是改为隐私
	art.Status = domain.ArticleStatusPrivate
	err := svc.repo.SyncStatus(ctx, art.Id, art.Author.Id, uint8(art.Status))
	return err
}

func (svc *articleService) GetById(ctx context.Context, id int64) (domain.Article, error) {
	art, err := svc.repo.GetById(ctx, id)
	return art, err
}

func (svc *articleService) GetPubById(ctx context.Context, id, uid int64) (domain.Article, error) {
	//获取文章详情的具体信息
	art, err := svc.repo.GetPubById(ctx, id, uid)
	//获取文章之后，还要异步进行阅读量的增加，使用kafka消息队列进行消费增加数量
	if err == nil {
		go func() {
			err2 := svc.producer.ProduceReadEvent(ctx, event.ReadEvent{
				Uid: uid,
				Aid: id,
			})
			if err2 != nil {
				svc.l.Error("发送读者阅读事件失败", logger.Error(err),
					logger.Int64("articleId", art.Id),
					logger.Int64("userId", uid))
			}
		}()

		////在生产者使用通道channel进行批量处理
		////使用它来在不同的 goroutine 之间安全地传递 readInfo 类型的数据。
		//go func() {
		//	svc.ch <- readInfo{
		//		Uid: uid,
		//		Aid: id,
		//	}
		//}()

	}

	return art, err
}
